package com.zx._01_基础._013_io;

import com.zx.common.Constant;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.junit.Test;

/**
 * 文件读取案例
 *
 * demo使用idea，spring boot项目，所有在不启动项目的时候，用户空间是项目模块的根目录
 */
public class Demo_02_Read {


    // 1. FileInputStream 读取一个字节
    @Test
    public void test1() throws IOException {
        InputStream is = new FileInputStream(Constant.io_read_text);
        //读取一个字节
        int i = is.read();
        System.out.println(i);
        is.close();
    }

    // 2. FileInputStream 读取整个文件。
    @Test
    public void test2() throws IOException {
        InputStream is = new FileInputStream(Constant.io_read_text);
        //读取多个字节
        byte[] b = new byte[20];//每次读取的字节数
        int hasRead = 0;
        //is.read(b) ,默认每次读取b.length个长度的字节，从b数组的0位置开始保存
        while ((hasRead = is.read(b)) > 0) {
            // 1.错误的读法，会多出写无效的数据
            //System.out.print(new String(b));
            // 2.正确的读法，从数组 0 开始读取，读取到 hasRead 的位置
            System.out.print(new String(b, 0, hasRead));
        }
        is.close();
    }

    // 3. 指定读取的位置。
    @Test
    public void test3() throws IOException {
        InputStream is = new FileInputStream(Constant.io_read_text);
        //读取多个字节，用处不是很大
        byte[] b = new byte[20];//每次读取的字节数
        int hasRead = 0;
        //is.read(b) 每次读取5个长度的字节，从b数组的2位置开始保存
        while ((hasRead = is.read(b, 0, hasRead)) > 0) {
            System.out.println(new String(b));
        }
        is.close();
    }

    // 4. 使用 FileReader 读取
    @Test
    public void test4() throws IOException {
        Reader re = new FileReader(Constant.io_read_text);
        //读取一个字节
        System.out.println((char) re.read());
    }

    // 4. 使用 FileReader 读取
    @Test
    public void test5() throws IOException {
        Reader re = new FileReader(Constant.io_read_text);
        //读取多个字节
        char[] c = new char[10];//每次读取的字节数
        int hasRead = 0;
        //re.read(b) ,默认每次读取c.length个长度的字节，从b数组的0位置开始保存
        while ((hasRead = re.read(c)) != -1) {
            // 1.错误的读法，会多出写无效的数据
            //System.out.print(new String(c));
            // 2.正确的读法，从数组 0 开始读取，读取到 hasRead 的位置
            System.out.print(new String(c, 0, hasRead));
        }
    }

    @Test
    public void test6() throws IOException {
        Reader re = new FileReader(Constant.io_read_text);
        //读取多个字节
        char[] c = new char[10];//每次读取的字节数
        int hasRead = 0;
        //re.read(b) 每次读取5个长度的字节，从b数组的2位置开始保存
        while ((hasRead = re.read(c, 2, 5)) != -1) {
            System.out.println(new String(c));
        }
    }

    @Test
    public void test7() throws IOException {
        try {
            // 初始化一个字节数组，内有5个字节的数据
            byte[] bytes = {1, 2, 3, 4, 5};
            // 用一个ByteArrayInputStream来读取这个字节数组
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            // 将ByteArrayInputStream包含在一个BufferedInputStream，并初始化缓冲区大小为2。
            BufferedInputStream bis = new BufferedInputStream(in, 20);
            // 读取字节1
            System.out.println("读取一个字节 “" + bis.read() + "”,并mark(1),表示以后最多只能读取1个字节");
            // 在字节2处做标记，同时设置readlimit参数为1
            // 根据JAVA文档mark以后最多只能读取1个字节，否则mark标记失效，但实际运行结果不是这样
            bis.mark(1);

            /*
             * 连续读取两个字节，超过了readlimit的大小，mark标记仍有效
             */
            // 连续读取两个字节
            System.out.print("连续读取两个字节“" + bis.read() + "”,“");
            System.out.println(bis.read() + "”,reset()使下次读取的字节回到mark(1)的位置");
            // 调用reset方法，未发生异常，说明mark标记仍有效。
            // 因为，虽然readlimit参数为1，但是这个BufferedInputStream类的缓冲区大小为2，
            // 所以允许读取2字节
            bis.reset();

            /*
             * 连续读取3个字节，超过了缓冲区大小，mark标记失效。
             * 在这个例子中BufferedInputStream类的缓冲区大小大于readlimit,
             * mark标记由缓冲区大小决定
             */
            // reset重置后连续读取3个字节，超过了BufferedInputStream类的缓冲区大小
            System.out.print("reset重置后连续读取3个字节" + bis.read() + ",");
            System.out.print(bis.read() + ",");
            System.out.println(bis.read() + ",");
            // 再次调用reset重置，抛出异常，说明mark后读取3个字节，mark标记失效
            System.out.println("reset again");
            bis.reset();
            System.out.print(bis.read() + ",");
            System.out.println(bis.read() + ",");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
